﻿using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ops.Exchange.Forwarder;
using Ops.Host.Core.Configuration;
using Ops.Host.Core.Management;
using Ops.Host.Core.Models;
using Ops.Host.Core.Utils;

namespace Ops.Host.Core.Services;

internal sealed class CustomService : ICustomService
{
    private readonly IFreeSql _freeSql;
    private readonly OpsHostOptions _opsHostOptions;
    private readonly ILogger _logger;

    public CustomService(IFreeSql freeSql, IOptions<OpsHostOptions> opsHostOptions, ILogger<CustomService> logger) 
    { 
        _freeSql = freeSql;
        _opsHostOptions = opsHostOptions.Value;
        _logger = logger;
    }

    private const string PLC_Sign_Card = nameof(PLC_Sign_Card); // 刷卡前缀
    private const string PLC_Sign_SpotCheck = nameof(PLC_Sign_SpotCheck); // 点检前缀

    public async Task<ReplyResult> SaveCustomAsync(ForwardData data)
    {
        // 刷卡
        if (data.Tag.StartsWith(PLC_Sign_Card))
        {
            return await SaveCardSwipingAsync(data);
        }

        // 点检
        if (data.Tag.StartsWith(PLC_Sign_SpotCheck))
        {
            return await SaveSpotCheckAsync(data);
        }

        return ReplyResultHelper.Ok();
    }

    // 刷卡
    private async Task<ReplyResult> SaveCardSwipingAsync(ForwardData data)
    {
        var ret = ReplyResultHelper.From(3); // 此处不返回 0，用 3 告知收到请求

        try
        {
            var num = data.Tag[(PLC_Sign_Card.Length + 1)..]; // 取末尾的序号
            var cardNo = data.GetString($"PLC_Card_CardNo_{num}"); // 发送过来的卡信息，其中包含设备信息。
            if (string.IsNullOrWhiteSpace(cardNo))
            {
                return ReplyResultHelper.Error(ErrorCode.ErrCardNoNotFound);
            }

            var (ok, cardNo1, cardDevice1) = SplitCard(cardNo.Trim());
            if (!ok)
            {
                _logger.LogWarning("[CustomService:CardSwiping] 卡号分隔异常，刷卡信息{0}；卡号：{1}；设备：{2}", cardNo, cardNo1, cardDevice1);
                return ReplyResultHelper.Error(ErrorCode.ErrCardNoNotFound);
            }

            // 检查卡号是否存在
            var cardInfo = _freeSql.Select<CardInfo>().Where(s => s.CardNo == cardNo1 && s.IsEnabled).ToOne();
            if (cardInfo == null)
            {
                return ReplyResultHelper.Error(ErrorCode.ErrCardNoNotFound);
            }

            CardSwiping item = new()
            {
                Station = data.Schema.Station,
                CardNo = cardNo1,
                Owner = cardInfo.Owner,
                CardDevice = data.Name,
                CardDeviceNum = cardDevice1,
                CreatedAt = DateTime.Now,
            };
            await _freeSql.Insert(item).ExecuteAffrowsAsync();

            // 回写卡号等级
            ret.AddValue($"MES_Card_Level_{num}", Convert.ToInt16((int)cardInfo!.PLevel));

            // 推送消息
            await MessageTaskQueueManager.Default.QueueAsync(new Message(item.Station, MessageClassify.CardSwiping, item.CardNo, (item.CardDevice, item.Owner)));

            return ret;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"[CustomService:CardSwiping] Error Tag：{data.Tag}");
            return ReplyResultHelper.Error();
        }

        (bool ok, string cardNo, string cardDevice) SplitCard(string card)
        {
            int len = _opsHostOptions.CardDeviceLength;
            // 刷卡信息长度必须大于刷卡机设备号长度
            if (card.Length <= len)
            {
                return (false, "", "");
            }

            // 设备号在前，卡号在后。
            return (true, card[len..], card[..len]);
        }
    }

    // 点检
    private async Task<ReplyResult> SaveSpotCheckAsync(ForwardData data)
    {
        try
        {
            var num = data.Tag[(PLC_Sign_SpotCheck.Length + 1)..]; // 取末尾的序号
            var item = data.GetInt($"PLC_SpotCheck_Item_{num}");
            var spotCheck = new SpotCheck
            {
                Station = data.Schema.Station,
                Tooling = data.Name,
                Item = item switch
                {
                    1 => "防错验证请求",
                    2 => "防错验证全无检测通过",
                    3 => "防错验证零件检测通过",
                    4 => "防错验证防漏防错通过",
                    5 => "防错验证完成",
                    _ => "",
                },
                Value = "",
                IsPass = true,
                CreatedAt = DateTime.Now,
            };

            await _freeSql.Insert(spotCheck).ExecuteAffrowsAsync();

            // 推送消息
            await MessageTaskQueueManager.Default.QueueAsync(new Message(spotCheck.Station, MessageClassify.SpotCheck, spotCheck.Tooling!, (spotCheck.Item, spotCheck.IsPass)));

            return ReplyResultHelper.Ok();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"[CustomService:SpotCheck] Error Tag：{data.Tag}");
            return ReplyResultHelper.Error();
        }
    }
}
